home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / snd / s_input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-11  |  20.7 KB  |  883 lines

  1. /* name:
  2.     input
  3.  
  4. function:
  5.     To accept the text of the message and allow ed, msg
  6.     to be called.
  7.  
  8. algorithm:
  9.     Input header information and text, then ask for a valid command
  10.  
  11. parameters:
  12.     none
  13.  
  14. returns:
  15.     With a null terminated letter in the string pointed to by
  16.     the global variable letter.
  17.  
  18. globals:
  19.     letter    address of the buffer.
  20.  
  21. calls:
  22.     write    system
  23.     printf
  24.     getchar
  25.     system  system
  26.  
  27. called by:
  28.     main
  29.  */
  30. /*
  31. **    R E V I S I O N  H I S T O R Y
  32. **
  33. **    03/31/83  GWH    Split the SEND program into component parts
  34. **
  35. **    04/05/83  GWH    Changed execl calls to execlp's.
  36. **
  37. **    11/21/83  GWH    Added directedit option.
  38. **
  39. **    05/29/84  GWH    Fixed a bug that allowed drafts created in an edit
  40. **            mode to be deleted if an interrupt was made by
  41. **            mistake. Also fixed a bug which resulted in the
  42. **            copy flag (cflag) being erroneously set.
  43. **
  44. **    04/02/85 M. Vasoll  Added the spelling checker command.
  45. **
  46. **    01/29/86 TRT    Changed the input scheme so that the user is placed
  47. **            directly into a visual editor, and is free to edit
  48. **            both the headers and body.  Also removed the
  49. **            following options:
  50. **                direct edit, header edit, input more body,
  51. **                delete body, visual edit (same as edit)
  52. */
  53.  
  54. #include "./s.h"
  55. #include "./s_externs.h"
  56.  
  57. extern  char *verdate;
  58. extern  int errno;
  59. extern    sigtype onint (), onint2(), onint3 ();
  60. int    bccflag;
  61.  
  62. input ()
  63. {
  64.     int     infile;
  65.     int     n;
  66.     long    dist;
  67.     int     nfd;
  68.     int     stat, slen;
  69.     char    otherbuf[S_BSIZE];
  70.     char    tempbuf[24];
  71.     char    *fromptr, *toptr, *ccptr, *subjptr, *bccptr, *otherptr;
  72.     int     (*old1) (),
  73.         (*old2) (),
  74.         (*old3) ();
  75.     register int    i;
  76.  
  77.     printf ("SND  (%s)\n", verdate);
  78.  
  79.     bccflag = 0;
  80.     dropen(DRBEGIN);
  81.  
  82. /*    Set up headers to be written into the draft file    */
  83.     fromptr = from;
  84.     toptr = to;
  85.     ccptr = cc;
  86.     subjptr = subject;
  87.     bccptr = bcc;
  88.     otherptr = otherbuf;
  89.  
  90.     strcpy(from, signature);
  91.     strcpy(otherptr, fromname);
  92.     strcat(otherptr, fromptr);
  93.     strcpy(fromptr, otherptr);
  94.  
  95.     strcpy(otherptr, toname);
  96.     strcat(otherptr, toptr);
  97.     strcpy(toptr, otherptr);
  98.  
  99.     strcpy(otherptr, ccname);
  100.     strcat(otherptr, ccptr);
  101.     strcpy(ccptr, otherptr);
  102.  
  103.     slen = strlen( subjname ); 
  104.     strcpy(otherptr, subjname);
  105.     strcat(otherptr, subjptr);
  106.     strcpy(subjptr, otherptr);
  107.     
  108. /*    Write the header info to the draft file        */
  109.  
  110.     if(write(drffd, fromptr, strlen(fromptr)) < 0)
  111.     {
  112.         printf("Cannot write draft %s\n", drffile);
  113.         s_exit(-1);
  114.     }
  115.     write(drffd, "\n", 1);
  116.     write(drffd, toptr, strlen(toptr));
  117.     write(drffd, "\n", 1);
  118.     write(drffd, ccptr, strlen(ccptr));
  119.     write(drffd, "\n", 1);
  120.  
  121. /*    If there are blind carbon copies write the necessary header b.s. */
  122.     if(bcc[0] != '\0')
  123.     {
  124.         strcpy(otherptr, bccname);
  125.         strcat(otherptr, bccptr);
  126.         strcpy(bccptr, otherptr);
  127.         write(drffd, bccptr, strlen(subjptr));
  128.         write(drffd, "\n", 1);
  129.  
  130.  
  131.         bccflag = 1;
  132.     }
  133.     if( strlen( subject ) > slen )
  134.     {
  135.         char newsubj[S_BSIZE], *p, *pnt;
  136.         char *index();
  137.         int plc;
  138.  
  139.         newsubj[0] = '\0';
  140.         pnt = subjptr;
  141.         while( (p = index(pnt,'\n')) != 0 )
  142.         {
  143.             *p++ = '\0';
  144.             plc = strlen(newsubj);
  145.             sprintf( &newsubj[plc],"%s\n%s",pnt," ");
  146.             pnt = p;
  147.         }
  148.         strcat( newsubj, pnt );
  149.         strcpy( subjptr, newsubj );
  150.     }
  151.     write(drffd, subjptr, strlen(subjptr));
  152.     write(drffd, "\n\n", 2);
  153.  
  154. /*    If there is a forwarded message        */
  155.     if (inclfile[0] != '\0')
  156.     {                             /* tack file to end of message        */
  157.         body = TRUE;
  158.         strcpy (bigbuf, inclfile);
  159.         infile = open (bigbuf, 0);
  160.         if (inclfile[0] != '\0')
  161.             inclfile[0] = '\0';
  162.         if (infile < 0)
  163.             printf ("can't open: '%s'\n", bigbuf);
  164.         dropen (DREND);
  165.         body = TRUE;
  166.         while ((i = read (infile, bigbuf, BBSIZE - 1)) > 0)
  167.             write (drffd, bigbuf, i);
  168.         (void) close (infile);
  169.     }
  170.  
  171. edit:
  172.  
  173.     fflush (stdout);
  174.  
  175.         drclose ();
  176.  
  177.         old1 =  signal (SIGHUP, SIG_IGN); /* ignore signals intended for edit */
  178.         old2 =  signal (SIGINT, SIG_IGN);
  179.         old3 =  signal (SIGQUIT, SIG_IGN);
  180.  
  181. /*    Crank up the editor now that the draft file is set-up    */
  182.         if (fork () == 0)
  183.         {
  184.         signal (SIGHUP, old1);
  185.         signal (SIGINT, orig);
  186.         signal (SIGQUIT, old3);
  187.  
  188.             execlp (editor, editor, drffile, (char *)0);
  189.  
  190.         fprintf (stderr,"can't execute\n");
  191.         s_exit (-1);
  192.         }
  193.         wait (&stat);
  194.         body = TRUE;    /* Don't know but assume he created a draft */
  195.         lastsend = 0;
  196.         signal (SIGHUP, old1);     /* restore signals */
  197.         signal (SIGINT, old2);
  198.         signal (SIGQUIT, old3);
  199.  
  200.         fflush (stdout);
  201.         signal (SIGINT, SIG_IGN);
  202.         signal (SIGQUIT, SIG_IGN);
  203.  
  204.     dropen(DRBEGIN);
  205.     
  206. /*    Rip the header information from the draft file and
  207. **    take care of any aliases
  208. **    Algorithm:
  209. **    Read each header line (function grabaddr), keeping track of the 
  210. **    number of characters read.  Handle the aliases (function doalias).
  211. **    Open a new file descriptor which points to the beginning of the
  212. **    draft file.  Read the draft file from the point where the header
  213. **    information leaves off while writing to the draft from the beginning.
  214. **    This effectively reads the header info, then shifts the body of the
  215. **    message up to the top of the draft, overwriting the header.
  216. */
  217.  
  218.     dist = gethdr( fromptr, toptr, ccptr, bccptr, subjptr );
  219.  
  220.     doalias( toptr );
  221.     doalias( ccptr );
  222.     doalias( bccptr );
  223.  
  224.     if(chmod(drffile, 0600) < 0)
  225.     {
  226.         fprintf(stderr,"Unable to make draft writable %s.\n", drffile);
  227.         s_exit(-1);
  228.     }
  229.     if((nfd = open(drffile, 2, 600)) < 0)
  230.     {
  231.         fprintf(stderr,"Could not open draft %s\n", drffile);
  232.         s_exit(-1);
  233.     }
  234.     if(lseek(nfd, 0L, 0) < 0)
  235.     {
  236.         fprintf(stderr,"Lseek failed on draft %s\n", drffile);
  237.         s_exit(-1);
  238.     }
  239.     if(lseek(drffd, dist-1, 0) < 0)
  240.     {
  241.         fprintf(stderr,"Lseek failed on draft %s\n", drffile);
  242.         s_exit(-1);
  243.     }
  244.  
  245.     dist = 0L;
  246.     while((i = read(drffd, bigbuf, BBSIZE -1)) > 0)
  247.         dist += write(nfd, bigbuf, i);
  248.  
  249.     if(truncate(drffile, dist) < 0)
  250.     {
  251.         fprintf(stderr,"Truncate failed on draft %s\n", drffile);
  252.         s_exit(-1);
  253.     }
  254.  
  255.     if(chmod(drffile, 0400) < 0)
  256.         fprintf(stderr,"Unable to make draft %s writable.\n",drffile);
  257.     
  258.     (void) close( nfd );
  259.  
  260.     setjmp (savej);
  261.     nsent = 0;
  262. /*
  263. **    MAIN COMMAND INTERPRETER LOOP
  264. */
  265.     for (;;)
  266.     {
  267.         char *cp;
  268.  
  269.     signal (SIGINT, onint3);
  270.     printf ("Command or ?: ");
  271.     fflush (stdout);
  272.     aborted = FALSE;
  273.     if (fgets (bigbuf, BBSIZE, stdin) == NULL)
  274.         goto byebye;
  275.         if (cp = index(bigbuf, '\n'))
  276.             *cp = '\0';
  277.  
  278. /*    "Set" option    */
  279.     if( strncmp( "set", bigbuf, 3) == 0){
  280.         char *av[NARGS];
  281.  
  282.         i = sstr2arg(bigbuf, 20, av, " \t");
  283.         if( i == 1 ) {    /* tell him what the current options are */
  284.             printf(" Copyfile  - '%s'\n", copyfile);
  285.             printf(" Signature - '%s'\n", signature);
  286.             printf(" Aliases   - '%s'\n", aliasfilename);
  287.             printf(" Editor    - '%s'\n", editor);
  288.             printf(" Checker   - '%s'\n", checker);
  289.             printf(" Subargs   - '%s'\n", subargs);
  290.  
  291.             if(qflag == 0 && cflag == 1)
  292.                 printf(" File copy option is on\n");
  293.             if(qflag == 1 && cflag == 0)
  294.                 printf(" File copy on confirmation only\n");
  295.             continue;
  296.         }
  297.         if( (i = picko( av[1] ) ) < 0) {
  298.             fprintf(stderr,"Option '%s' is invalid.\n", av[1]);
  299.             continue;
  300.         }
  301.         select_o( i, &av[1] );
  302.         continue;
  303.     }
  304.     compress (bigbuf, bigbuf);
  305.                   /* so prefix works on multi-words     */
  306.     if (bigbuf[0] == '\0')
  307.         continue;             /* just hit newline                   */
  308.  
  309.     signal (SIGINT, onint);
  310.  
  311.     for (i = 0; !isnull (bigbuf[i]); i++)
  312.         bigbuf[i] = uptolow (bigbuf[i]);
  313.  
  314.     if (prefix ("bcc", bigbuf))
  315.     {
  316.         getaddr (bccname, bcc, YES, locname);
  317.         bccflag = 1;    
  318.         continue;
  319.     }
  320.  
  321. /*    "Edit" option (grandfathered to also accept "v" for visual edit) */
  322.  
  323.     if (prefix ("edit body", bigbuf) || prefix("visual edit body", bigbuf))
  324.     {
  325.         dropen( DRBEGIN );
  326.             if((tmpfd = open(tmpdrffile, 2, 0600)) < 0)
  327.             {
  328.                 fprintf(stderr,"Cannot open temporary draft file %s\n", tmpdrffile);
  329.                 s_exit(-1);
  330.             }
  331.  
  332.             if(lseek(tmpfd, 0L, 0) < 0)
  333.             {
  334.                 fprintf(stderr,"Lseek failed on temporary draft file %s\n", tmpdrffile);
  335.                 s_exit(-1);
  336.             }
  337.  
  338.             if(chmod(drffile, 0600) < 0)
  339.                 fprintf(stderr,"Could not make draft %s writable\n", drffile);
  340.  
  341.         /*     Write the header info to the temporary draft    */
  342.         dist = 0L;
  343.         dist += write(tmpfd, fromname, strlen( fromname ));
  344.             dist += write(tmpfd, from, strlen( from ));
  345.             dist += write(tmpfd, "\n", 1);
  346.             dist += write(tmpfd, toname, strlen( toname ));
  347.             dist += write(tmpfd, to, strlen( to ));
  348.             dist += write(tmpfd, "\n", 1);
  349.             dist += write(tmpfd, ccname, strlen( ccname ));
  350.             dist += write(tmpfd, cc, strlen( cc ));
  351.             dist += write(tmpfd, "\n", 1);
  352.             if(bccflag)
  353.             {
  354.                 dist += write(tmpfd, bccname, strlen( bccname ));
  355.                 dist += write(tmpfd, bcc, strlen( bcc ));
  356.                 dist += write(tmpfd, "\n", 1);
  357.             }
  358.             dist += write(tmpfd, subjname, strlen( subjname ));
  359.             dist += write(tmpfd, subject, strlen( subject ));
  360.             dist += write(tmpfd, "\n", 1);
  361.  
  362.         if(lseek(drffd, 0L, 0) < 0)
  363.         {
  364.              fprintf(stderr,"Lseek failed on draft %s\n", drffile);
  365.              s_exit(-1);
  366.         }
  367.             if(lseek(tmpfd, 0L, 2) < 0)
  368.             {
  369.                 fprintf(stderr,"Lseek failed on temporary draft\n");
  370.                 s_exit(-1);
  371.             }
  372.  
  373.         /*    Write the body into the temp. draft    */
  374.             while((i = read(drffd, bigbuf, BBSIZE-1)) > 0)
  375.                 dist += write(tmpfd, bigbuf, i);
  376.  
  377.             if(truncate( tmpdrffile, dist) < 0)
  378.             {
  379.                 fprintf(stderr,"Could not truncate temporary draft\n");
  380.                 s_exit(-1);
  381.             }
  382.  
  383.             if(lseek(tmpfd, 0L, 0) < 0)
  384.                 fprintf(stderr,"Lseek failed on temporary draft\n");
  385.             if(lseek(drffd, 0L, 0) < 0)
  386.                 fprintf(stderr,"Lseek failed on draft %s\n", drffile);
  387.             
  388.             dist = 0L;
  389.         /*    Copy temp. draft which contains headers and
  390.         **    body back into draft file
  391.         */
  392.             while((i = read(tmpfd, bigbuf, BBSIZE-1)) > 0)
  393.                 dist += write(drffd, bigbuf, i);
  394.  
  395.             if(truncate( drffile, dist ) < 0)
  396.                 fprintf(stderr,"Could not truncate draft %s\n", drffile);
  397.             if(truncate( tmpdrffile, 0 ) < 0)
  398.                 fprintf(stderr,"Could not truncate temporary draft\n");
  399.             if(close( tmpfd ) < 0)
  400.                 fprintf(stderr,"Could not close temporary draft\n");
  401.             if(lseek(drffd, 0L, 0) < 0)
  402.                 fprintf(stderr,"Lseek failed on draft %s\n", drffile);
  403.             if(chmod(drffile, 0400) < 0)
  404.                 fprintf(stderr,"Could not protect draft %s\n", drffile);
  405.         /*    Fire-up the editor    */
  406.         goto edit;
  407.     }
  408. /*    "File include" option    */
  409.     if (prefix ("file include", bigbuf))
  410.     {
  411.         printf ("File: ");
  412.         gather (bigbuf, BBSIZE - 1);
  413.         if (bigbuf[0] == '\0')
  414.         continue;
  415.  
  416.         infile = open (bigbuf, 0);
  417.         if (inclfile[0] != '\0')
  418.         {                     /* and include file                   */
  419.         inclfile[0] = '\0';
  420.         }
  421.         if (infile < 0)
  422.         {
  423.         fprintf(stderr,"can't open: '%s'\n", bigbuf);
  424.         continue;
  425.         }
  426.         dropen (DREND);
  427.         body = TRUE;
  428.         while ((i = read (infile, bigbuf, BBSIZE - 1)) > 0)
  429.         write (drffd, bigbuf, i);
  430.         (void) close (infile);
  431.         printf (" ...included\n");
  432.         continue;
  433.     }
  434. /*    "Program run" option    */
  435.     if (prefix ("program run", bigbuf))
  436.     {
  437.         printf ("Program: ");
  438.         fflush (stdout);
  439.         if (gets (tempbuf) == NULL)
  440.         continue;
  441.         drclose ();
  442.  
  443.         /* ignore signals intended for subprocess */
  444.         old1 = signal (SIGHUP, SIG_IGN);
  445.         old2 = signal (SIGINT, SIG_IGN);
  446.         old3 = signal (SIGQUIT, SIG_IGN);
  447.  
  448.         if (fork () == 0)
  449.         {
  450.         signal (SIGHUP, old1);
  451.         signal (SIGINT, orig);
  452.         signal (SIGQUIT, old3);
  453.         execlp ("sh", "send-shell", "-c", tempbuf, (char *)0);
  454.         fprintf(stderr,"can't execute\n");
  455.         s_exit (-1);
  456.         }
  457.         wait (&stat);
  458.         signal (SIGHUP, old1);     /* restore signals */
  459.         signal (SIGINT, old2);
  460.         signal (SIGQUIT, old3);
  461.         dropen (DREND);
  462.         continue;
  463.     }
  464. /*    "quit" option    */
  465.     if (prefix ("quit", bigbuf) ||
  466.         prefix ("bye", bigbuf))
  467.     {
  468.     byebye: 
  469.         if ( body && !nsent)
  470.         {
  471.         printf ("Without sending draft");
  472.         if (confirm ())
  473.             return;
  474.         else
  475.             continue;
  476.         }
  477.         drclose ();
  478.         return;
  479.     }
  480. /*    "review message" option    */
  481.     if (prefix ("review message", bigbuf))
  482.     {
  483.         dropen( DRBEGIN );
  484.         /*    Put header info into temp. draft    */
  485.         if((nfd = open(tmpdrffile, 2, 0600)) < 0)
  486.         {
  487.             fprintf(stderr,"Can't open temporary file\n");
  488.             s_exit(-1);
  489.         }
  490.         if(lseek(nfd, 0L, 0) < 0)
  491.         {
  492.             fprintf(stderr,"Lseek failed on temporary file\n");
  493.             s_exit(-1);
  494.         }
  495.         if(write(nfd, fromname, strlen( fromname )) < 0)
  496.         {
  497.             fprintf(stderr,"Cannot write temporary file\n");
  498.             s_exit(-1);
  499.         }
  500.         write(nfd, from, strlen( from ));
  501.         write(nfd, "\n", 1);
  502.         if(to[0] != '\0')
  503.         {
  504.             write(nfd, toname, strlen( toname ));
  505.             write(nfd, to, strlen( to ));
  506.             write(nfd, "\n", 1);
  507.         }
  508.         else if(bccflag)
  509.         {
  510.             write(nfd, toname, strlen( toname ));
  511.             write(nfd, "list: ;", 7);
  512.             write(nfd, "\n", 1);
  513.         }
  514.         if(cc[0] != '\0')
  515.         {
  516.             write(nfd, ccname, strlen( ccname ));
  517.             write(nfd, cc, strlen( cc ));
  518.             write(nfd, "\n", 1);
  519.         }
  520.         if(bccflag)
  521.         {
  522.             write(nfd, bccname, strlen( bccname ));
  523.             write(nfd, bcc, strlen( bcc ));
  524.             write(nfd, "\n", 1);
  525.         }            
  526.         if(subject[0] != '\0')
  527.         {
  528.             write(nfd, subjname, strlen( subjname ));
  529.             write(nfd, subject, strlen( subject ));
  530.             write(nfd, "\n", 1);
  531.         }
  532.  
  533.         if(lseek(drffd, 0L, 0) < 0)
  534.             fprintf(stderr,"Lseek failed on draft %s\n", drffile);
  535.     /*    Write the body into the temp. file    */
  536.         while((i = read(drffd, bigbuf, BBSIZE - 1)) > 0)
  537.             write(nfd, bigbuf, i);
  538.         drclose();
  539.        if(pflag)
  540.        {
  541.         (void) close( nfd );
  542.             
  543.             /* ignore signals intended for subprocess */
  544.             old1 = signal (SIGHUP, SIG_IGN);
  545.             old2 = signal (SIGINT, SIG_IGN);
  546.             old3 = signal (SIGQUIT, SIG_IGN);
  547.         /*    Start-up "more" program on the temp. draft    */
  548.             if (fork () == 0)
  549.             {
  550.             signal (SIGHUP, old1);
  551.             signal (SIGINT, orig);
  552.             signal (SIGQUIT, old3);
  553.             execlp ("more", "-c", tmpdrffile, 0);
  554.             fprintf(stderr,"can't execute\n");
  555.             s_exit (-1);
  556.             }
  557.             wait (&stat);
  558.             signal (SIGHUP, old1);     /* restore signals */
  559.             signal (SIGINT, old2);
  560.             signal (SIGQUIT, old3);
  561.  
  562.        }
  563.        else    /*    If the paging option is off, just show it */
  564.        {
  565.         if( lseek(nfd, 0L, 0) < 0 )
  566.             fprintf(stderr, "Lseek failed on temporary draft.\n");
  567.  
  568.         while((i = read(nfd, bigbuf, BBSIZE - 1)) > 0)
  569.             write( 1, bigbuf, i);
  570.  
  571.         (void) close( nfd );
  572.        }
  573.        if(truncate(tmpdrffile, 0) < 0)
  574.         fprintf(stderr,"truncate failed on temp. draft\n");
  575.  
  576.        fflush( stdout );
  577.        continue;
  578.     }
  579. /*    "Check spelling" option    */
  580.     if (prefix ("check spelling", bigbuf))
  581.     {
  582.         drclose ();
  583.  
  584.         old1 =  signal (SIGHUP, SIG_IGN); /* ignore signals intended for cheker */
  585.         old2 =  signal (SIGINT, SIG_IGN);
  586.         old3 =  signal (SIGQUIT, SIG_IGN);
  587.  
  588.         if (fork () == 0)
  589.         {
  590.         signal (SIGHUP, old1);
  591.         signal (SIGINT, orig);
  592.         signal (SIGQUIT, old3);
  593.         execlp (checker, checker, drffile, (char *)0);
  594.         fprintf(stderr,"can't execute\n");
  595.         s_exit (-1);
  596.         }
  597.         wait (&stat);
  598.         signal (SIGHUP, old1);     /* restore signals */
  599.         signal (SIGINT, old2);
  600.         signal (SIGQUIT, old3);
  601.         dropen (DREND);
  602.         continue;
  603.     }
  604. /*    "Post message" option    */
  605.     if (prefix ("post message", bigbuf) ||
  606.         prefix ("send message", bigbuf))
  607.     {
  608.         if (lastsend && lastsend == body)
  609.         {
  610.         printf ("Without changing anything");
  611.         if (!confirm ())
  612.             break;
  613.         }
  614.         signal (SIGINT, onint2);
  615.         if( qflag == 1 ){
  616.         printf(" Do you want a file copy of this message ?  ");
  617.         fflush(stdout);
  618.         fgets(tempbuf, sizeof(tempbuf), stdin );
  619.         if( tempbuf[0] == 'y' || tempbuf[0] == 'Y' || tempbuf[0] == '\n')
  620.             cflag = 1;
  621.             else
  622.                 cflag = 0;
  623.         }
  624.         post ();
  625.         if ( qflag == 1 )
  626.         cflag = 0;
  627.  
  628. /* *** auto-exit, upon successfull send, since draft is saved *** */
  629.  
  630.         goto byebye;
  631.     }
  632. /*    help    */
  633.     if (prefix ("?", bigbuf))
  634.     {
  635.         printf ("bcc\n");
  636.         printf ("bye\n");
  637.         printf ("check spelling\n");
  638.         printf ("edit body\n");
  639.         printf ("file include\n");
  640.         printf ("program run\n");
  641.         printf ("quit\n");
  642.         printf ("review message\n");
  643.         printf ("send message\n");
  644.         printf ("set [option] [option value]\n");
  645.         continue;
  646.     }
  647.  
  648.     printf (" unknown command (type ? for help)\n");
  649.     }                  /* end of loop */
  650. }
  651.  
  652. do_review (name, data)            /* send out a header field            */
  653.     char name[],                  /* name of field                      */
  654.     *data;                    /* value-part of field                */
  655. {
  656.     register int ind;
  657.     register char *curptr;
  658.  
  659.     for (curptr = data, ind = 0; ind >= 0; curptr += ind + 1)
  660.     {
  661.     if ((ind = strindex ("\n", curptr)) >= 0)
  662.         curptr[ind] = '\0';   /* format lines properly              */
  663.  
  664.     printf (hdrfmt, (curptr == data) ? name : "", curptr);
  665.     if (ind >= 0)
  666.         curptr[ind] = '\n';   /* put it back                        */
  667.     }
  668. }
  669.  
  670. doalias( bufptr )
  671. char *bufptr;
  672. {
  673.     char tbuf[512], *bptr;
  674.  
  675.     tbuf[0] = '\0';
  676.     bptr = tbuf;
  677.     aliasmap( bptr, bufptr, host );
  678.     strcpy( bufptr, bptr );
  679. }
  680.  
  681. /*
  682.  *            G E T H D R
  683.  *
  684.  * This routine seeks to the beginning of the message in the disk file,
  685.  * reads in the header, and scans it to find the values of the various
  686.  * fields.  Fields which the caller is not interested are passed as
  687.  * NULLs.
  688.  *
  689.  */
  690. gethdr( fromstr, tostr, ccstr, bccstr, subjstr )
  691. char *fromstr;        /* where to save From     field */
  692. char *tostr;        /* where to save To       field */
  693. char *ccstr;        /* where to save cc       field */
  694. char *bccstr;        /* where to save BCC      field */
  695. char *subjstr;        /* where to save Subj     field */
  696. {
  697.     char line[LINESIZE];
  698.     char curhdr[S_BSIZE];
  699.     int cnt = 0;
  700.  
  701.     if( fromstr != 0)
  702.         fromstr[0] = '\0';
  703.     if( tostr != 0)
  704.         tostr[0] = '\0';
  705.     if( ccstr != 0)
  706.         ccstr[0] = '\0';
  707.     if( bccstr != 0)
  708.         bccstr[0] = '\0';
  709.     if( subjstr != 0)
  710.         subjstr[0] = '\0';
  711.     
  712.     dropen( DRBEGIN );
  713.     curhdr[0] = '0';
  714.     while((cnt += gethdrline( line )) > 0 &&
  715.         line[0] != '\0' &&
  716.         strcmp( delim1, line) != 0 &&
  717.         strcmp( delim2, line) != 0 )  
  718.     {
  719.         if( fromstr != 0 && isnull( fromstr[0]))
  720.             if( gothdr( curhdr, "From:", line, fromstr))
  721.                 continue;
  722.  
  723.         if( tostr != 0)
  724.             if( gothdr( curhdr, "To:", line, tostr))
  725.                 continue;
  726.  
  727.         if( ccstr != 0)
  728.             if( gothdr( curhdr, "cc:", line, ccstr))
  729.                 continue;
  730.  
  731.          if( bccstr != 0)
  732.              if( gothdr( curhdr, "BCC:", line, bccstr))
  733.                  continue;
  734.                  
  735.         if( subjstr != 0)
  736.             if( gothdr( curhdr, "Subject:", line, subjstr))
  737.                 continue;
  738.  
  739.         /*
  740.          * If we got here, the line was of a type that we don't
  741.          * care about.  Zap curhdr, as it will not have been updated
  742.          * unless the line was processed by gothdr(), and we want
  743.          * to avoid processing extraneous continuations.
  744.          */
  745.          strcpy( curhdr, "boring-header-line:" );
  746.     }
  747.     if(*bccstr != '\0')
  748.         bccflag = 1;
  749.     return( cnt );
  750. }
  751.  
  752. /*
  753.  *            G O T H D R
  754.  */
  755. gothdr( curname, name, src, dest)
  756. char *curname;        /* current field name */
  757. char *name;        /* test field name */
  758. char *src;        /* test input line */
  759. char *dest;        /* where to put data part at end */
  760. {
  761.     unsigned int destlen;
  762.     char *ptr;
  763.  
  764.     if( isspace( *src ) )
  765.     {
  766.         /* This is a continuation line.  Check "remembered" field */
  767.         if( strcmp( curname, name ) != 0 )
  768.             return( FALSE );
  769.  
  770.         /* Continuation of correct header line.  Retain "remembered"
  771.         /* field.  Get rid of name & extra space from input line. */
  772. /*        compress( src, src);    */
  773.  
  774.         /*** FALL OUT ***/
  775.     }
  776.     else if (prefix( src, name ))
  777.     {
  778.         /* New line and field name matches, lets go! */
  779.  
  780.         /* Remember the "current field" */
  781.         strcpy( curname, name);
  782.  
  783.         /* get rid of name & extra space */
  784.         compress( &src[strlen( name )], src);
  785.  
  786.         /*** FALL OUT ***/
  787.     }
  788.     else
  789.     {
  790.         /* New line but field does not match, skip it */
  791.         return(FALSE);
  792.     }
  793.  
  794.     /* Common code for TRUE replies */
  795.  
  796.     if( isnull( dest[0]))  {
  797.         /* first entry */
  798.         strcpy( dest, src);
  799.     }  else  {
  800.         /* add to end of field, if room */
  801.         destlen = strlen( dest);
  802.         if( (strlen( src) + destlen) < S_BSIZE - 2)
  803.             sprintf( &dest[destlen], "\n %s%c", src, '\0');
  804.         else
  805.         {
  806.             ptr = &src[S_BSIZE - 2];
  807.             while(*ptr != ' ' && *ptr != ',')
  808.                 ptr--;
  809.             *ptr = '\0';
  810.             sprintf( &dest[destlen], "\n %s%c",src, '\0');
  811.             fprintf(stderr,"WARNING: Header line exceeds buffer size!\n");
  812.             fprintf(stderr,"\tIt was truncated to legal length.\n");
  813.         }
  814.     }
  815.     return( TRUE);
  816. }
  817. gethdrline( s )
  818. char *s;
  819. {
  820.     int c, i;
  821.     
  822.     i = 0;
  823.     while( read( drffd, s, 1 ) > 0 && *s != '\n' )
  824.     {
  825.         s++;
  826.         i++;
  827.     }
  828.     *s = '\0';
  829.     return( i+1 );
  830. }
  831.  
  832. #ifndef V4_2BSD
  833.  
  834. #define BUFSIZE        1024
  835.  
  836. static char tmp_file[] = "/tmp/truncXXXXXX";
  837.  
  838. truncate(path, length)
  839. char *path;
  840. long length;
  841. {
  842.     char tmpf[sizeof tmp_file];
  843.     register fd1, fd2, n;
  844.     char buf[BUFSIZE];
  845.  
  846.     if ((fd1 = open(path, 0)) < 0)
  847.         return -1;
  848.     strcpy(tmpf, tmp_file);
  849.     mktemp(tmpf);
  850.     if ((fd2 = creat(tmpf, 0600)) < 0) {
  851.         close(fd1);
  852.         return -1;
  853.     }
  854.     close(fd2);
  855.     if ((fd2 = open(tmpf, 2)) < 0) {
  856.         close(fd1);
  857.         unlink(tmpf);
  858.         return -1;
  859.     }
  860.     while (length > 0) {
  861.         n = length > BUFSIZE ? BUFSIZE : length;
  862.         if ((n = read(fd1, buf, n)) <= 0)
  863.             break;
  864.         write(fd2, buf, n);
  865.         length -= n;
  866.     }
  867.     close(fd1);
  868.     if ((fd1 = creat(path, 0666)) < 0) {
  869.         close(fd2);
  870.         unlink(tmpf);
  871.         return -1;
  872.     }
  873.     lseek(fd2, 0L, 0);
  874.     while ((n = read(fd2, buf, BUFSIZE)) > 0)
  875.         write(fd1, buf, n);
  876.     close(fd1);
  877.     close(fd2);
  878.     unlink(tmpf);
  879.     return 0;
  880. }
  881.  
  882. #endif V4_2BSD
  883.